<template>
  <div>
    <div class="aTxMap" :id="id" :style="{ height: height + 'px' }" />
  </div>
</template>

<script>
export default {
  name: "aTxMap",
  model: {
    prop: "value",
    event: "change",
  },
  props: {
    value: {
      type: Object,
      default() {
        return {};
      },
    },

    id: {
      type: String,
      default: function () {
        return "tmap-" + +new Date() + ((Math.random() * 1000).toFixed(0) + "");
      },
    },

    lngKey: {
      type: String,
      default: "longitude",
    },

    latKey: {
      type: String,
      default: "latitude",
    },

    height: {
      type: Number,
      default: 500,
    },
  },

  data() {
    return {
      deleteForKeyword: false,

      load: false,
      map: null,
      editorLayer: null,
      markerLayer: null,
      markerLayerLoadedQueue: [],
      markerId: "",
    };
  },

  mounted() {
    this.init();
  },

  beforeDestroy() {
    this.destoryMap();
  },

  destroyed() {
    this.destoryMap();
  },

  methods: {
    // 加载 CDN
    init() {
      this.initMap();
    },

    // 初始化地图
    initMap() {
      this.map = new window.TMap.Map(this.id, { zoom: 12 });
      this.setMarkerLayer();
      this.markerLayerLoadedQueue.map((cb) => cb());
    },

    // 销毁地图
    destoryMap() {
      if (this.map) {
        this.map.destroy();
        this.map = null;
      }
    },

    // 初始化 MarkerLayer 图层
    setMarkerLayer() {
      this.markerLayer = new window.TMap.MultiMarker({
        map: this.map,
        styles: {
          highlight: new window.TMap.MarkerStyle({
            src: "https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker-pink.png",
          }),
        },
        geometries: [],
      });

      this.setGeometryEditor();
    },

    // 初始化几何图形及编辑器
    // 编辑器暂无主动帮助用户选择的api
    setGeometryEditor() {
      this.editorLayer = new window.TMap.tools.GeometryEditor({
        map: this.map,
        overlayList: [
          {
            id: "marker-layer",
            overlay: this.markerLayer,
            selectedStyleId: "highlight",
          },
        ],
        actionMode: window.TMap.tools.constants.EDITOR_ACTION.INTERACT, // 编辑器的工作模式
        activeOverlayId: "marker-layer", // 激活图层
        selectable: true,
      });

      // 移动
      this.editorLayer.on("adjust_complete", (e) => {
        this.$set(this.value, this.lngKey, e.position.lng);
        this.$set(this.value, this.latKey, e.position.lat);
      });

      /**
       * 删除 => deleteKey | editor.delete() 无法区分是用 .delete 跟键盘 delete 进行删除
       * 不监听 delete 跟禁止键盘 delete，否则移动 marker 的时候移动不了编辑层选中的 marker 有毒！
       *
       * 1. window.addEventListener('keydown') 添加键盘删除标识来区分 .delete 跟键盘 delete
       *    delete_complete 比 window 回调更早
       */
      // this.editorLayer.on('delete_complete', e => {
      //   this.$set(this.value, this.lngKey, '')
      //   this.$set(this.value, this.latKey, '')
      // })
    },

    // 设置 marker
    setMarker({ lng, lat }) {
      // 当前地图/图标图层未初始化，则塞进队列中等待执行
      // ps: 当前队列只有一个，后期多图标再自行修改
      if (!this.map || !this.markerLayer || !this.editorLayer) {
        this.$set(this.markerLayerLoadedQueue, 0, () => {
          this.setMarker({ lng, lat });
        });
        return;
      }

      // 不存在经纬度删除当前 marker
      if (!lng) {
        this.removeMarker();
        return;
      }

      const lngRes = (lng * 1000) / 1000;
      const latRes = (lat * 1000) / 1000;
      const target = { lng: lngRes, lat: latRes };
      !this.markerId ? this.initMarker(target) : this.moveMarker(target);
    },

    // 初始 marker
    initMarker({ lng, lat }) {
      const markerId = `${new Date().getTime()}${Math.random().toString(10)}`;
      const position = new window.TMap.LatLng(lat, lng);

      this.map.setCenter(position);
      // 需要在当前地图区域加载完成后才能添加，否则可能出现添加不成功
      // 丢，tilesloaded 在平移到已加载完成地点无法触发
      setTimeout(() => {
        this.markerLayer.add([{ id: markerId, position: position }]);
        this.markerId = markerId;
      }, 800);
    },

    // 移动 marker
    moveMarker({ lng, lat }) {
      this.editorLayer.delete();
      const position = new window.TMap.LatLng(lat, lng);
      this.map.setCenter(position);
      this.markerLayer.updateGeometries({ id: this.markerId, position });
    },

    // 删除 marker
    removeMarker() {
      if (!this.markerId) return;
      this.editorLayer.delete();
      this.markerLayer.remove([this.markerId]);
      this.markerId = "";
    },
  },
};
</script>

<style>
.aTxMap {
  /* height: 300px; */
  z-index: 0;
}
</style>